// #pragma once
// #ifndef __THREAD_HPP__

// #include <iostream>
// #include <string>
// #include <functional>
// #include <pthread.h>
// #include <sys/types.h>
// #include <unistd.h>

// namespace ThreadModule
// {

//     enum class T_STATUS{
//         NEW,
//         RUNNING,
//         STOP,
//     };

//     // template<class T>
//     // using Thread<T>::func_t = std::function<void(T)>;
//     template <class T>
//     class Thread
//     {
//         using func_t = std::function<void(T)>;
//     private:
//         static void *Routine(void *arg){
//             Thread *thread = (Thread*)arg;
//             thread->_stat = T_STATUS::RUNNING;
//             thread->_func(thread->_data);
//             return nullptr;
//         }
//         void EnableDetach(){ _joinable = false; }

//     public:
//         Thread(func_t func, T data)
//             : _stat(T_STATUS::NEW), _func(func), _joinable(true)
//         {
//             _data = data;
//             _name = "Thread-" + std::to_string(++nr_thread);
//             _pid = getpid();
//         }
//         bool Start()
//         {
//             if(_stat != T_STATUS::RUNNING)
//             {
//                 // int ret = pthread_create(&_tid, nullptr, Routine, nullptr);
//                 int ret = pthread_create(&_tid, nullptr, Routine, this);
//                 if(ret != 0) return false;
//                 return true;
//             }
//             return false;
//         }
//         bool Stop()
//         {
//             if(_stat == T_STATUS::RUNNING)
//             {
//                 int ret = pthread_cancel(_tid);
//                 if(ret != 0) return false;
//                 _stat = T_STATUS::STOP;
//                 return true;
//             }
//             return false;
//         }
//         bool Join()
//         {
//             if(_joinable)
//             {
//                 int ret = ::pthread_join(_tid, nullptr);
//                 if(ret != 0) return false;
//                 _stat = T_STATUS::STOP;
//                 return true;
//             }
//             return false;
//         }

//         void Detach()
//         {
//             EnableDetach();
//             pthread_detach(_tid);
//         }
//         bool IsJoinable(){ return _joinable; }
//         std::string Name(){ return _name; }
//         ~Thread(){}
//     private:
//         func_t _func;
//         std::string _name;
//         pthread_t _tid;
//         pid_t _pid;
//         T_STATUS _stat;
//         bool _joinable;
//         T _data;

//         static int nr_thread;
//     };
//     template<class T>
//     int ThreadModule::Thread<T>::nr_thread = 0;

// }

// #define __THREAD_HPP__

// #endif






#ifndef __THREAD_HPP__

#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>

namespace ThreadModule
{

    enum class T_STATUS{
        NEW,
        RUNNING,
        STOP,
    };

    
    class Thread
    {
        using func_t = std::function<void(std::string name)>; 
    private:
        static void *Routine(void *arg){
            Thread *thread = (Thread*)arg;
            thread->_stat = T_STATUS::RUNNING;
            thread->_func(thread->Name());
            return nullptr;
        }
        void EnableDetach(){ _joinable = false; }

    public:
        Thread(func_t func)
            : _stat(T_STATUS::NEW), _func(func), _joinable(true)
        {
            _name = "Thread-" + std::to_string(++nr_thread);
            _pid = getpid();
        }
        bool Start()
        {
            if(_stat != T_STATUS::RUNNING)
            {
                // int ret = pthread_create(&_tid, nullptr, Routine, nullptr);
                int ret = pthread_create(&_tid, nullptr, Routine, this);
                if(ret != 0) return false;
                return true;
            }
            return false;
        }
        bool Stop()
        {
            if(_stat == T_STATUS::RUNNING)
            {
                int ret = pthread_cancel(_tid);
                if(ret != 0) return false;
                _stat = T_STATUS::STOP;
                return true;
            }
            return false;
        }
        bool Join()
        {
            if(_joinable)
            {
                int ret = ::pthread_join(_tid, nullptr);
                if(ret != 0) return false;
                _stat = T_STATUS::STOP;
                return true;
            }
            return false;
        }

        void Detach()
        {
            EnableDetach();
            pthread_detach(_tid);
        }
        bool IsJoinable(){ return _joinable; }
        std::string Name(){ return _name; }
        ~Thread(){}
    private:
        func_t _func;
        std::string _name;
        pthread_t _tid;
        pid_t _pid;
        T_STATUS _stat;
        bool _joinable;

        static int nr_thread;
    };

}
int ThreadModule::Thread::nr_thread = 0;

#define __THREAD_HPP__

#endif


// #ifndef _THREAD_HPP__
// #define _THREAD_HPP__

// #include <iostream>
// #include <string>
// #include <pthread.h>
// #include <functional>
// #include <sys/types.h>
// #include <unistd.h>

// // // v2
// // namespace ThreadModule
// // {
// //     static int number = 1;
// //     enum class TSTATUS
// //     {
// //         NEW,
// //         RUNNING,
// //         STOP
// //     };

// //     template <typename T>
// //     class Thread
// //     {
// //         using func_t = std::function<void(T)>;
// //     private:
// //         // 成员方法！
// //         static void *Routine(void *args)
// //         {
// //             Thread<T> *t = static_cast<Thread<T> *>(args);
// //             t->_status = TSTATUS::RUNNING;
// //             t->_func(t->_data);
// //             return nullptr;
// //         }
// //         void EnableDetach() { _joinable = false; }

// //     public:
// //         Thread(func_t func, T data) : _func(func), _data(data), _status(TSTATUS::NEW), _joinable(true)
// //         {
// //             _name = "Thread-" + std::to_string(number++);
// //             _pid = getpid();
// //         }
// //         bool Start()
// //         {
// //             if (_status != TSTATUS::RUNNING)
// //             {
// //                 int n = ::pthread_create(&_tid, nullptr, Routine, this); // TODO
// //                 if (n != 0)
// //                     return false;
// //                 return true;
// //             }
// //             return false;
// //         }
// //         bool Stop()
// //         {
// //             if (_status == TSTATUS::RUNNING)
// //             {
// //                 int n = ::pthread_cancel(_tid);
// //                 if (n != 0)
// //                     return false;
// //                 _status = TSTATUS::STOP;
// //                 return true;
// //             }
// //             return false;
// //         }
// //         bool Join()
// //         {
// //             if (_joinable)
// //             {
// //                 int n = ::pthread_join(_tid, nullptr);
// //                 if (n != 0)
// //                     return false;
// //                 _status = TSTATUS::STOP;
// //                 return true;
// //             }
// //             return false;
// //         }
// //         void Detach()
// //         {
// //             EnableDetach();
// //             pthread_detach(_tid);
// //         }
// //         bool IsJoinable() { return _joinable; }
// //         std::string Name() { return _name; }
// //         ~Thread()
// //         {
// //         }

// //     private:
// //         std::string _name;
// //         pthread_t _tid;
// //         pid_t _pid;
// //         bool _joinable; // 是否是分离的，默认不是
// //         func_t _func;
// //         TSTATUS _status;
// //         T _data;
// //     };
// // }

// //v1
// namespace ThreadModule
// {
//     using func_t = std::function<void()>;
//     static int number = 1;
//     enum class TSTATUS
//     {
//         NEW,
//         RUNNING,
//         STOP
//     };

//     class Thread
//     {
//     private:
//         // 成员方法！
//         static void *Routine(void *args)
//         {
//             Thread *t = static_cast<Thread *>(args);
//             t->_status = TSTATUS::RUNNING;
//             t->_func();
//             return nullptr;
//         }
//         void EnableDetach() { _joinable = false; }

//     public:
//         Thread(func_t func) : _func(func), _status(TSTATUS::NEW), _joinable(true)
//         {
//             _name = "Thread-" + std::to_string(number++);
//             _pid = getpid();
//         }
//         bool Start()
//         {
//             if (_status != TSTATUS::RUNNING)
//             {
//                 int n = ::pthread_create(&_tid, nullptr, Routine, this); // TODO
//                 if (n != 0)
//                     return false;
//                 return true;
//             }
//             return false;
//         }
//         bool Stop()
//         {
//             if (_status == TSTATUS::RUNNING)
//             {
//                 int n = ::pthread_cancel(_tid);
//                 if (n != 0)
//                     return false;
//                 _status = TSTATUS::STOP;
//                 return true;
//             }
//             return false;
//         }
//         bool Join()
//         {
//             if (_joinable)
//             {
//                 int n = ::pthread_join(_tid, nullptr);
//                 if (n != 0)
//                     return false;
//                 _status = TSTATUS::STOP;
//                 return true;
//             }
//             return false;
//         }
//         void Detach()
//         {
//             EnableDetach();
//             pthread_detach(_tid);
//         }
//         bool IsJoinable() { return _joinable; }
//         std::string Name() {return _name;}
//         ~Thread()
//         {
//         }

//     private:
//         std::string _name;
//         pthread_t _tid;
//         pid_t _pid;
//         bool _joinable; // 是否是分离的，默认不是
//         func_t _func;
//         TSTATUS _status;
//     };
// }

// #endif